package com.xbongbong.saas.analytical.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.team.TeamUserHelp;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.constant.RegExConstant;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.QuotationErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.saas.analytical.SaasValidateAnalyticalService;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.dictionary.ArchivedEnum;
import com.xbongbong.saas.enums.product.QuotationProductEnum;
import com.xbongbong.saas.help.AnalyticalHelp;
import com.xbongbong.saas.help.SaasDataInitHelp;
import com.xbongbong.saas.help.SaasProductHelp;
import com.xbongbong.saas.help.SaveFormatHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getDoubleOrDefaultFromFormData;

/**
 * @author 吴峰
 * @date 2021/07/15 17:15
 */
@Service("quotationAnalyticalServiceImpl")
public class QuotationValidateAnalyticalServiceImpl implements SaasValidateAnalyticalService {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(QuotationValidateAnalyticalServiceImpl.class);
    
    @Resource
    private TeamUserHelp teamUserHelp;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private SaasProductHelp saasProductHelp;
    @Resource
    private AnalyticalHelp analyticalHelp;

    @Override
    public List<Integer> type() {
        return Arrays.asList(XbbRefTypeEnum.QUOTATION.getCode());
    }

    @Override
    public void analyticalData(ValidateDataDTO validateDataDTO) throws XbbException {
        beforeSave(validateDataDTO);
        teamUserHelp.beforeVerifyUserTeam(validateDataDTO);
    }
    
    public void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException {
        try {
            JSONObject data = validateDataDTO.getData();
            String corpid = validateDataDTO.getCorpid();
            Long quotationId = validateDataDTO.getDataId();
            SaveFormatHelp.formatLinkBusiness4Save(data, QuotationEnum.CUSTOMER_ID.getAttr(), QuotationEnum.CUSTOMER_NAME.getAttr(), QuotationEnum.CUSTOMER_NAME.getFieldType());
            SaveFormatHelp.formatLinkBusiness4Save(data, QuotationEnum.CONTACT_ID.getAttr(), QuotationEnum.CONTACT_NAME.getAttr(), QuotationEnum.CONTACT_NAME.getFieldType());
            SaveFormatHelp.formatLinkBusiness4Save(data, QuotationEnum.OPPORTUNITY_ID.getAttr(), QuotationEnum.OPPORTUNITY_NAME.getAttr(), QuotationEnum.OPPORTUNITY_NAME.getFieldType());
            boolean isNew = analyticalHelp.isNew(validateDataDTO.getDataId(), validateDataDTO.getTaskId(), validateDataDTO.getCorpid());

            //无报价人导入
            if (Objects.equals(validateDataDTO.getNoSignImport(), 1)) {
                //这时候会多一个离职，要去掉
                String signName = data.getString(QuotationEnum.QUOTATION_NAME.getAttr());
                if ( StringUtil.isNotEmpty(signName) ) {
                    signName = signName.replaceAll(StringConstant.LEAVE_MARK,"");
                    data.put(QuotationEnum.QUOTATION_NAME.getAttr(),data.getString(QuotationEnum.QUOTATION_NAME.getAttr()));
                }
                SaveFormatHelp.formatLinkBusiness4Save(data, QuotationEnum.QUOTATION_PERSON.getAttr(), QuotationEnum.QUOTATION_NAME.getAttr(), FieldTypeEnum.LINK_BUSINESS_SINGLE.getType());
            }

            //版本号必须是以1.0,2.0这样结尾
            if (Objects.equals(validateDataDTO.getIsImport(), 1)) {
                Object version = data.get(QuotationEnum.VERSION.getAttr());
                String versions = Objects.toString(version, "");
                //正整数的情况下，给他补成.0结尾的格式
                if (versions.matches(RegExConstant.QUOTATION_INTFER)) {
                    StringBuilder stringBuilder = new StringBuilder();
                    stringBuilder.append(versions);
                    stringBuilder.append(".0");
                    versions = stringBuilder.toString();
                    data.put(QuotationEnum.VERSION.getAttr(), versions);
                }
                if (!versions.matches(RegExConstant.QUOTATION_VERSION)) {
                    throw new XbbException(QuotationErrorCodeEnum.API_ERROR_246007);
                }
            }

            //有效日前大于报价日前校验
            if (Objects.nonNull(data.get(QuotationEnum.EFFECTIVE_TIME.getAttr())) && Objects.nonNull(data.get(QuotationEnum.QUOTATION_TIME.getAttr()))) {
                Long date_2 = data.getLong(QuotationEnum.EFFECTIVE_TIME.getAttr());
                Long date_1 = data.getLong(QuotationEnum.QUOTATION_TIME.getAttr());
                if (date_1 > date_2) {
                    throw new XbbException(QuotationErrorCodeEnum.API_ERROR_246003);
                }
            }

            if (isNew) {
                // 是否归档，1归档，2未归档
                data.put(QuotationEnum.ARCHIVED.getAttr(), ArchivedEnum.UN_ARCHIVED.getCode());
                data.put(QuotationEnum.IS_NEW.getAttr(), BasicConstant.ONE);
                if (data.get(QuotationEnum.GROUP_NUMBER.getAttr()) == null) {
                    data.put(QuotationEnum.GROUP_NUMBER.getAttr(), validateDataDTO.getGroupNumber());
                }
                if (Objects.isNull(data.get(QuotationEnum.DISCOUNT.getAttr()))) {
                    data.put(QuotationEnum.DISCOUNT.getAttr(), 1);
                }
            }

            Boolean productCanSee = true;
            if (!isNew){
                productCanSee = commonHelp.attrCanSee(validateDataDTO.getExplainMap().get(QuotationEnum.PRODUCT.getAttr()),quotationId,validateDataDTO.getCreatorId(),validateDataDTO.getLoginUser(),corpid,XbbRefTypeEnum.QUOTATION.getCode());
            }
            if (isNew || productCanSee){
                JSONArray productArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(data,QuotationEnum.PRODUCT.getAttr(),new JSONArray());
                //校验报价单产品
                validateProductDemo(productArr,corpid);
                // 预计成本，预计毛利，预计毛利率计算
                calculateAmount(validateDataDTO);
            }

            for (Map.Entry<String,Object> entry : SaasDataInitHelp.initQuotation().entrySet()){
                SaasDataInitHelp.antDataSet(data,entry.getKey(),entry.getValue());
            }
            // 我也不知道这行代码的意义和逻辑是什么，反正能解决问题23481
            if (Objects.isNull(validateDataDTO.getGroupNumber()) && Objects.nonNull(data.getString(QuotationEnum.GROUP_NUMBER.getAttr()))) {
                validateDataDTO.setGroupNumber(data.getString(QuotationEnum.GROUP_NUMBER.getAttr()));
            }
            data.put(QuotationEnum.GROUP_NUMBER.getAttr(),validateDataDTO.getGroupNumber());
            validateDataDTO.setData(data);
            Map<String,Boolean> attrCanSeeMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            attrCanSeeMap.put(QuotationEnum.PRODUCT.getAttr(),productCanSee);
            SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo = new SaasNeedRedundantAttrPojo();
            saasNeedRedundantAttrPojo.setAttrCanSeeMap(attrCanSeeMap);
            validateDataDTO.setSaasNeedRedundantAttrPoJo(saasNeedRedundantAttrPojo);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("quotationAnalyticalServiceImpl.beforeSave error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }
    /**
     * 预计成本，预计毛利，预计毛利率计算
     * @param validateDataDTO
     * @throws XbbException
     * @author long.rao
     * @date 2019-08-19 17:08
     */
    private void calculateAmount(ValidateDataDTO validateDataDTO) throws XbbException{
        JSONObject contractData = validateDataDTO.getData();
        JSONArray productList = FastJsonHelper.getJsonArrOrDefaultFromFormData(contractData, QuotationEnum.PRODUCT.getAttr(), new JSONArray());
        Double estimateCost = 0D;
        if (productList != null) {
            for (Object object : productList) {
                JSONObject product = (JSONObject) object;
                Double productNum = getDoubleOrDefaultFromFormData(product, QuotationProductEnum.NUM.getAttr(), 0D);
                Double productCost = getDoubleOrDefaultFromFormData(product, QuotationEnum.ESTIMATE_COST.getSaasAttr(), 0D);
                estimateCost = Arith.add(estimateCost, Arith.mul(productNum, productCost));
            }
        }
        // 优惠不计入成本
        Double surchargeAmount = getDoubleOrDefaultFromFormData(contractData, QuotationEnum.OTHER_EXPENSE.getAttr(), BasicConstant.ZERO_DOUBLE);
        Double contractCost = Arith.add(estimateCost, surchargeAmount);
        // 预计成本(=产品总成本+其他费用)
        contractData.put(QuotationEnum.ESTIMATE_COST.getAttr(), contractCost);

        Double amount = getDoubleOrDefaultFromFormData(contractData, QuotationEnum.AMOUNT.getAttr(), 0D);
        // 预计毛利(=预计金额-产品成本-其它费用)
        double grossProfit = Arith.sub(Arith.sub(amount, estimateCost), surchargeAmount);
        contractData.put(QuotationEnum.GROSS_PROFIT.getAttr(), grossProfit);
        // 预计毛利率(=预估毛利/报价金额)
        if (Double.compare(amount, BasicConstant.ZERO_DOUBLE) != 0) {
            contractData.put(QuotationEnum.GROSS_PROFIT_RATE.getAttr(), Arith.div(grossProfit, amount));
        } else {
            contractData.put(QuotationEnum.GROSS_PROFIT_RATE.getAttr(), BasicConstant.ZERO_DOUBLE);
        }
    }
    /**
     * 报价单产品校验
     * @param productList
     * @param corpid
     * @throws XbbException
     */
    private void validateProductDemo(JSONArray productList, String corpid) throws XbbException {
        Set<Long> pageProductIds = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (Objects.isNull(productList) || productList.isEmpty()){
            return;
        }
        for (Object obj : productList){
            JSONObject json = JSONObject.parseObject(obj.toString());
            Long productId = json.getLong(SelectProductEnum.PRODUCT.getAttr());
            pageProductIds.add(productId);
        }
        saasProductHelp.productExitContract(productList,corpid,new ArrayList<>(pageProductIds));
    }
}
